package com.aplink.generic.adapter;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;

import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.location.Location;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.aplink.generic.constant.type.ActionType;
import com.aplink.generic.constant.type.ColumnType;
import com.aplink.generic.pojo.ColumnSetting;
import com.aplink.generic.pojo.GenericObject;
import com.aplink.generic.util.DateTimeUtils;
import com.aplink.generic.util.LogUtil;
import com.aplink.generic.util.ResourcesHelper;
import com.aplink.generic.util.objectrule.Target;
import com.aplink.generic.widgets.ApLinkGoogleMaps;
import com.aplink.generic.widgets.hacky.MapWrapperLayout;
import com.aplink.generic.widgets.hacky.OnInfoWindowElemTouchListener;
import com.aplink.sg.R;
import com.google.android.gms.maps.GoogleMap.InfoWindowAdapter;
import com.google.android.gms.maps.model.Marker;

public class GoogleMapInfoWindowAdapter implements InfoWindowAdapter {
	private final ApLinkGoogleMaps mApLinkGoogleMaps;
	private final ArrayList<ColumnSetting> mColumnSettings;
	private final HashMap<ColumnSetting, View> mColumnViews;
	private TextView mDistanceView;
	private final HashMap<ColumnSetting, OnInfoWindowElemTouchListener> mElemTouchListener;
	private final int mInfoWinfowDesign;
	private final MapWrapperLayout mMapWrapperLayout;
	private View mRoot;

	public GoogleMapInfoWindowAdapter(ApLinkGoogleMaps googleMaps,
			ArrayList<ColumnSetting> columnSettings, int infoWindowsDesign,
			MapWrapperLayout mapWrapperLayout) {
		mColumnSettings = columnSettings;
		mInfoWinfowDesign = infoWindowsDesign;
		mMapWrapperLayout = mapWrapperLayout;
		mApLinkGoogleMaps = googleMaps;
		mColumnViews = new HashMap<>();
		mElemTouchListener = new HashMap<>();
		init();
	}

	@Override
	public View getInfoContents(final Marker marker) {
		final GenericObject mSelectedObject = mApLinkGoogleMaps
				.getSelectedObject();
		if (!mSelectedObject.getMarker().getId()
				.equalsIgnoreCase(marker.getId())) {
			return null;
		}
		for (final ColumnSetting columnSetting : mColumnSettings) {
			View child = mColumnViews.get(columnSetting);
			final ColumnType columnType = columnSetting.getColType();
			final String columnName = columnSetting.getColumnName();
			String columnValue = "";
			if (!TextUtils.isEmpty(mSelectedObject.getValue(columnName))) {
				columnValue = mSelectedObject.getValue(columnName).toString();
			} else if (columnSetting.isStaicResource()) {
				if (mSelectedObject.containsKey(ColumnSetting.STATIC_RESOURCE)
						&& (mSelectedObject
								.getValue(ColumnSetting.STATIC_RESOURCE) != null)) {
					columnValue = mSelectedObject.getValue(
							ColumnSetting.STATIC_RESOURCE).toString();
				} else {
					columnValue = "";
				}
			}
			if (columnSetting.hasValueList()) {
				columnValue = columnSetting.getValueList().get(columnValue);
				if (TextUtils.isEmpty(columnValue)) {
					columnValue = columnSetting.getValueList().get(
							columnSetting.getValueList().getDefaultValue());
				}
			}
			if (columnType.equals(ColumnType.Button)) {
				child.setTag(mSelectedObject);
				mElemTouchListener.get(columnSetting).setMarker(marker);
			} else if (child instanceof TextView) {
				String content = "";
				if (columnType.equals(ColumnType.DateTime)) {
					try {
						final long miliseconds = Long.parseLong(columnValue);
						if (TextUtils.isEmpty(columnSetting.getFormat())) {
							content = DateTimeUtils.getDateTime(miliseconds,
									null);
						} else {
							content = DateTimeUtils.getDateTime(miliseconds,
									columnSetting.getFormat());
						}
					} catch (final NumberFormatException e) {
						LogUtil.error(e.getMessage(), "getView", getClass()
								.getSimpleName());
					} catch (final ParseException e) {
						LogUtil.error(e.getMessage(), "getView", getClass()
								.getSimpleName());
					}
				} else if (columnType.equals(ColumnType.Text)) {
					content = columnValue;
				} else if (columnType.equals(ColumnType.Money)) {
					final Double number = Double.valueOf(columnValue);
					final DecimalFormat dec = new DecimalFormat(
							columnSetting.getFormat());
					content = dec.format(number);
				}
				((TextView) child).setText(content);
			}
		}
		if (mDistanceView != null) {
			String distance = null;

			Location currentLocation = new Location("currentLocation");
			currentLocation
					.setLongitude(mApLinkGoogleMaps.getCurrentLocation().longitude);
			currentLocation
					.setLatitude(mApLinkGoogleMaps.getCurrentLocation().latitude);

			Location markerLocation = new Location("markerLocation");
			markerLocation.setLongitude(marker.getPosition().longitude);
			markerLocation.setLatitude(marker.getPosition().latitude);
			float dist = currentLocation.distanceTo(markerLocation);
			if (dist < 1000) {
				distance = String.format(Locale.getDefault(), "%.2f m", dist);
			} else {
				distance = String.format(Locale.getDefault(), "%.2f Km",
						(dist / 1000f));
			}
			mDistanceView.setText(distance);
		}
		mMapWrapperLayout.setMarkerWithInfoWindow(marker, mRoot);
		return mRoot;
	}

	@Override
	public View getInfoWindow(Marker marker) {
		return null;
	}

	private void init() {
		LayoutInflater vi = (LayoutInflater) this.mApLinkGoogleMaps
				.getGenericFragment().getApplicationContext()
				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mRoot = vi.inflate(mInfoWinfowDesign, null);
		for (final ColumnSetting columnSetting : mColumnSettings) {
			int viewID = ResourcesHelper.getViewIdByName(columnSetting
					.getLinkMappingName());
			View child = mRoot.findViewById(viewID);
			mColumnViews.put(columnSetting, child);
			final ColumnType columnType = columnSetting.getColType();
			if (columnType.equals(ColumnType.Button)) {
				OnInfoWindowElemTouchListener elemTouchListener = new OnInfoWindowElemTouchListener(
						child) {
					@Override
					protected void onClickConfirmed(View v, Marker marker) {
						GenericObject mSelectedObject = (GenericObject) v
								.getTag();
						if (columnSetting.getActionType().equals(
								ActionType.GET_DIRECTION)) {
							mApLinkGoogleMaps.getDirection(marker);
						} else if (columnSetting.getActionType().equals(
								ActionType.NEXT_PAGE)) {
							try {
								Target targetActivity;
								targetActivity = columnSetting
										.getTargetCollection().getTargetClass(
												mSelectedObject);
								mApLinkGoogleMaps
										.getGenericFragment()
										.startActivity(
												targetActivity.getTargetClass(),
												targetActivity
														.getPassingValue(),
												mSelectedObject);
							} catch (NameNotFoundException
									| ClassNotFoundException e) {
								e.printStackTrace();
							}
						}
					}
				};
				child.setOnTouchListener(elemTouchListener);
				mElemTouchListener.put(columnSetting, elemTouchListener);
			}
		}
		mDistanceView = (TextView) mRoot.findViewById(R.id.TEXTVIEW_DISTANCE);
	}

}
